/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef RENDER_SERVICE_MAIN_RENDER_SERVER_RS_RENDER_MULTI_PROCESS_MANAGER_H
#define RENDER_SERVICE_MAIN_RENDER_SERVER_RS_RENDER_MULTI_PROCESS_MANAGER_H

#include <cstdint>
#include <event_handler.h>
#include <future>
#include <memory>
#include <mutex>
#include <refbase.h>
#include <string>
#include <unordered_map>

#include "rs_render_process_manager.h"
#include "irs_composer_connection.h"
#include "render_process/transaction/zidl/rs_iservice_to_render_connection"
#include "platform/ohos/transaction/zidl/rs_iclient_to_render_connection"
#include "rs_render_mode_config.h"

namespace OHOS {
namespace Rosen {
class RSRenderComposerManager;
class RSRenderComposerAgent;
class RSMultiRenderProcessManager : public RSRenderProcessManager {
public:
    RSMultiRenderProcessManager(RSRenderService& renderService);
    ~RSMultiRenderProcessManager() noexcept override = default;

    sptr<IRemoteObject> OnScreenConnected(ScreenId id, const ScreenEventData& data, const RSScreenProperty& property) override;
    void OnScreenDisconnected(ScreenId id, const ScreenEventData& data) override;
    void OnScreenPropertyChanged(ScreenId id, const RSScreenProperty& property) override;
    void OnFrameRefresh() override;
    void OnVBlankIdle(ScreenId id, uint64_t ns) override;
    void OnVirtualScreenConnected(ScreenId id) override;
    void OnVirtualScreenDisconnected(ScreenId id) override;

    void RecordRenderProcessConnection(pid_t pid, sptr<RSIServiceToRenderConnection> serviceToRenderConnection, sptr<RSIClientToRenderConnection> clientToRenderConnection);
    pid_t GetRenderProcessPid(GroupId groupId);
    sptr<RSScreenProperty> GetPendingScreenProperty(pid_t pid);
    std::promise<bool>& GetRenderProcessReadyPromise(pid_t pid);

    sptr<RSIServiceToRenderConnection> GetServiceToRenderConn(ScreenId screenId) override;
    std::vector<sptr<RSIServiceToRenderConnection>> GetServiceToRenderConns() override;
    sptr<RSIClientToRenderConnection> GetClientToRenderConn(ScreenId screenId) override;

private:
    mutable std::mutex mutex_;

    sptr<IRemoteObject> HandleExistGroup(GroupId groupId, ScreenId screenId, cosnt RSScreenProperty& property);
    sptr<IRemoteObject> HandleNewGroup(GroupId groupId, ScreenId screenId, cosnt RSScreenProperty& property);
    GroupId GetGroupId(ScreenId screenId);

    std::unordered_map<GroupId, pid_t> groupIdToRenderProcessPid_;
    std::unordered_map<pid_t, sptr<RSIServiceToRenderConnection>> serviceToRenderConnections_;
    std::unordered_map<pid_t, sptr<RSIClientToRenderConnection>> clientToRenderConnections_;
    std::unordered_map<pid_t, std::promise<bool>> renderProcessReadyPromises_;

    struct PendingScreenConnectInfo {
        ScreenId screenId = INVALID_SCREEN_ID;
        sptr<RSScreenProperty> property = nullptr;
    };
    std::unordered_map<pid_t, PendingScreenConnectInfo> pendingScreenConnectInfos_;
};
} // namespace Rosen
} // namespace OHOS

#endif // RENDER_SERVICE_MAIN_RENDER_SERVER_RS_RENDER_MULTI_PROCESS_MANAGER_H